import angular from 'angular';
import confirmTemplate from './confirm.template.html';

function ConfirmProvider() {
  var defaults = {
    title: '确认',
    content: '您确定要执行此操作吗？',
    type: 'warning',
    okText: '确定',
    cancelText: '取消',
    showCancelButton: true,
    showConfirmButton: true
  };

  this.setDefaults = function setDefaults(options) {
    if (options) {
      angular.extend(defaults, options);
    }
  };

  this.$get = [
    '$rootScope',
    '$compile',
    '$timeout',
    '$document',
    '$q',
    function getConfirm($rootScope, $compile, $timeout, $document, $q) {
      function attachElement(element) {
        var body = $document.find('body');
        body.append(element);
      }

      function teardown(scope, element) {
        element.remove();
        scope.$destroy();
      }

      function scheduleHide(scope, element, callback) {
        scope.visible = false;
        $timeout(function runCallback() {
          if (angular.isFunction(callback)) {
            callback();
          }
          teardown(scope, element);
        }, 300);
      }

      return {
        show: function(options) {
          var deferred = $q.defer();
          var scope = $rootScope.$new();
          var config = angular.extend({}, defaults, options || {});

          scope.config = config;
          scope.visible = false;

          var element;
          var isClosing = false;

          function closeWith(isConfirmed) {
            if (isClosing) {
              return;
            }
            isClosing = true;

            if (isConfirmed) {
              deferred.resolve();
            } else {
              deferred.reject();
            }

            scheduleHide(scope, element);
          }

          scope.confirm = function confirm() {
            closeWith(true);
          };

          scope.cancel = function cancel() {
            closeWith(false);
          };

          scope.handleOverlayClick = function handleOverlayClick() {
            if (!config.showCancelButton && config.showConfirmButton) {
              scope.confirm();
            } else if (config.showCancelButton) {
              scope.cancel();
            }
          };

          scope.handleClose = function handleClose() {
            if (!config.showCancelButton && config.showConfirmButton) {
              scope.confirm();
            } else {
              scope.cancel();
            }
          };

          element = $compile(confirmTemplate)(scope);
          attachElement(element);

          $timeout(function show() {
            scope.visible = true;
          }, 10);

          return deferred.promise;
        }
      };
    }
  ];
}

export default ConfirmProvider;
